using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Data;
using System.Data.Common;
using Vb = Microsoft.VisualBasic;
using System.Windows.Forms;
using System.Collections;
using ACFramework;

namespace ACSeguridad
{
   /// <summary>
   /// Clase utilitaria para validar usuario y otros procedimientos asociados a la validacion del usuario.
   /// </summary>
   public class ACValidarUsuario
   {
      #region Variables

      private string m_send_user_passusr;
      private string m_sql_user;
      private string m_sql_process;
      private bool m_password;
      private bool m_proceso;
      private bool m_empresa;
      private bool m_validarPassword;
      private bool m_cargado;

      private dbConexion m_conexion;
      private ACTypeAlgorithm m_algorithm;
      private ACDataConexion m_dataconexion;
      private ACDataUsuario m_datausuario;

      private List<EProcesos> m_listProcesos;

      public enum Operacion
      {
         ValidarUsuarioPassword
         ,ValidarProceso
         ,ValidarVariosProcesos
      }
      #endregion

      #region Propiedades

      /// <summary>
      /// Codigo del usuario Ejemplo: YSAACX
      /// </summary>
      public String ACUSER_codUsr
      {
         get { return m_datausuario.USER_CodUsr; }
         set { m_datausuario.USER_CodUsr = value; }
      }

      /// <summary>
      /// Descripcion del usuario Ejemplo: Usuario administrador
      /// </summary>
      public String ACUSER_Desc
      {
         get { return m_datausuario.USER_Desc; }
         set { m_datausuario.USER_Desc = value; }
      }

      /// <summary>
      /// Nombres del usuario: Ysaacx 
      /// </summary>
      public String ACUSER_Nombre
      {
         get
         {
            if (m_datausuario.USER_Nombre == null)
               return "";
            else
               return m_datausuario.USER_Nombre;
         }
         set { m_datausuario.USER_Nombre = value; }
      }

      /// <summary>
      /// Empresa
      /// </summary>
      public bool ACEmpresa
      {
         get { return m_empresa; }
         set { m_empresa = value; }
      }

      /// <summary>
      /// Codigo interno del usuario
      /// </summary>
      public int ACUSER_IdUser
      {
         get { return Convert.ToInt32(m_datausuario.USER_IdUser); }
         set { m_datausuario.USER_IdUser = value; }
      }

      /// <summary>
      /// Booleano para confirmar si la contraseña y el usuario fue correctamente validada
      /// </summary>
      public bool ACPassword
      {
         get { return m_password; }
         set { m_password = value; }
      }

      /// <summary>
      /// Booleano para confirmar si el usuario tiene permiso para ejecutar el proceso que intenta ejecutar.
      /// </summary>
      public bool ACProceso
      {
         get { return m_proceso; }
         set { m_proceso = value; }
      }

      /// <summary>
      /// EL nivel de seguridad del usuario
      /// </summary>
      public string ACNIVE_CodNivel
      {
         get { return m_datausuario.NIVE_CodNivel; }
      }

      /// <summary>
      /// Verifica si se ha cargado el usuario correctamente, o si el usuario existe.
      /// </summary>
      public bool ACCargado
      {
         get { return m_cargado; }
         set { m_cargado = value; }
      }

      public List<EProcesos> ListProcesos
      {
         get { return m_listProcesos; }
         set { m_listProcesos = value; }
      }
      #endregion

      #region Contructores

      #region Operaciones con la validación del usuario

      /// <summary>
      /// Constructor por defecto, selecciona el algoritmos por defecto que es MD5
      /// </summary>
      public ACValidarUsuario() { m_algorithm = ACTypeAlgorithm.csAlgorithmPassMd5New; }

      /// <summary>
      /// Constructor que recibe valores para conexion a la base de datos
      /// </summary>
      /// <param name="x_dc">Clase que contiene los datos de conexion</param>
      public ACValidarUsuario(ACDataConexion x_dc)
      {
         try
         {
            m_validarPassword = true;
            DAEnterpriseValidate.Instanciar(x_dc.Servidor, x_dc.BaseDatos, x_dc.UsuarioBD, x_dc.PasswordBD);
            m_algorithm = ACTypeAlgorithm.csAlgorithmPassMd5New;
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Constructor que recibe datos de conexion y el usuarios que intenta conectarse
      /// </summary>
      /// <param name="_dc">Clase que contiene los datos de conexion</param>
      /// <param name="usercrea">Usuario que esta ejecurando el proceso de conexion</param>
      public ACValidarUsuario(ACDataConexion x_dc, string usercrea)
      {
         try
         {
            m_validarPassword = true;
            DAEnterpriseValidate.Instanciar(x_dc.Servidor, x_dc.BaseDatos, x_dc.UsuarioBD, x_dc.PasswordBD);
            m_algorithm = ACTypeAlgorithm.csAlgorithmPassMd5New;
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Constructor que recibe datos de conexion y datos del usuario a ser validado en la base de datos
      /// </summary>
      /// <param name="x_dc">Clase que contiene los datos de conexion</param>
      /// <param name="x_du">Datos del usuario que quiere validarse en la base de datos</param>
      public ACValidarUsuario(ACDataConexion x_dc, ACDataUsuario x_du)
      {
         try
         {
            m_validarPassword = true;
            DAEnterpriseValidate.Instanciar(x_dc.Servidor, x_dc.BaseDatos, x_dc.UsuarioBD, x_dc.PasswordBD);
            m_algorithm = x_dc.Algoritmo;
            m_datausuario = x_du;
            m_dataconexion = x_dc;
            encriptar();
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Constructor
      /// </summary>
      /// <param name="_dc"></param>
      /// <param name="_du"></param>
      /// <param name="_validarPassword"></param>
      public ACValidarUsuario(ACDataConexion x_dc, ACDataUsuario x_du, bool x_validarPassword)
      {
         try
         {
            m_validarPassword = x_validarPassword;
            DAEnterpriseValidate.Instanciar(x_dc.Servidor, x_dc.BaseDatos, x_dc.UsuarioBD, x_dc.PasswordBD);
            m_algorithm = x_dc.Algoritmo;
            m_datausuario = x_du;
            m_dataconexion = x_dc;
            encriptar();
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      public ACValidarUsuario(ACDataConexion x_dc, ACDataUsuario x_du, Operacion x_opcion)
      {
         try
         {
            DAEnterpriseValidate.Instanciar(x_dc.Servidor, x_dc.BaseDatos, x_dc.UsuarioBD, x_dc.PasswordBD);
            m_algorithm = x_dc.Algoritmo;
            m_datausuario = x_du;
            m_dataconexion = x_dc;
            switch (x_opcion)
            {
               case Operacion.ValidarUsuarioPassword:
                  m_validarPassword = true;
                  encriptar();
                  break;
               case Operacion.ValidarProceso:
                  m_validarPassword = false;
                  encriptar();
                  break;
               case Operacion.ValidarVariosProcesos:
                  m_validarPassword = false;
                  EncriptarMultiple();
                  break;
               default:
                  m_validarPassword = true;    
                  break;
            }         
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Constructor que recibe los datos de conexion y un usuario de validacion, asi como el tipo de algoritmo que se usara
      /// para la validacion de su contraseña
      /// </summary>
      /// <param name="_dc"></param>
      /// <param name="_du"></param>
      /// <param name="x_algorithm"></param>
      public ACValidarUsuario(ACDataConexion x_dc, ACDataUsuario x_du, ACTypeAlgorithm x_algorithm)
      {
         try
         {
            DAEnterpriseValidate.Instanciar(x_dc.Servidor, x_dc.BaseDatos, x_dc.UsuarioBD, x_dc.PasswordBD);
            m_algorithm = x_algorithm;
            m_datausuario = x_du;
            m_dataconexion = x_dc;
            encriptar();
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      #endregion

      #endregion

      #region Menu

      //#region generar el menu
      //private string m_valueMenu;
      //private List<EPlantillas> l_Plantillas;

      //public string ValueMenu
      //{
      //   get { return m_valueMenu; }
      //   set { m_valueMenu = value; }
      //}

      ///// <summary>
      ///// Genera el menu, pasando todos sus valores a una lista
      ///// </summary>
      ///// <param name="_menu">El Objeto tipo MenuStrip enviado por referencia</param>
      //private void GenerarMenu(ref System.Windows.Forms.MenuStrip _menu)
      //{
      //   try
      //   {
      //      m_valueMenu = "";
      //      EPlantillas _plantilla = new EPlantillas();
      //      CargarPlantilla(ref _plantilla, 0, 0, m_dataconexion.APLI_CodApli, "A");
      //      l_Plantillas = new List<EPlantillas>();
      //      l_Plantillas.Add(_plantilla);

      //      int i = 1;
      //      foreach (System.Windows.Forms.ToolStripMenuItem Item in _menu.Items)
      //      {
      //         m_valueMenu += i.ToString() + "\t" + Item.Text + " \n";
      //         EPlantillas m_plantilla = new EPlantillas();
      //         CargarPlantilla(ref m_plantilla, i, 0, Item.Text, "A");
      //         l_Plantillas.Add(m_plantilla);
      //         if (Item.DropDownItems.Count > 0)
      //         {
      //            GenerarMenu(Item.DropDownItems, ref m_valueMenu, ref i, ref l_Plantillas);
      //         }
      //         i++;
      //      }
      //      string query = String.Format("DELETE FROM PlantillasMenu WHERE APLI_CodApli = '{0}'", m_dataconexion.APLI_CodApli.Trim());
      //      DAEnterpriseValidate.AsignarProcedure(query, System.Data.CommandType.Text);
      //      DAEnterpriseValidate.ExecuteNonQuery();
      //      GenerarMenu(ref l_Plantillas);
      //   }
      //   catch (Exception ex)
      //   {
      //      ACDialogos.MostrarMensajeError("Generador de Menu's", "No puede generar el menu, revise el detalle y vuelva a intentarlo", ex);
      //   }
      //}

      ///// <summary>
      ///// Funcion que se utiliza recursivamente para poder obtener todos los niveles del menus, e ingresarlos en una lista para
      ///// ser procesados posteriormente
      ///// </summary>
      ///// <param name="_Item">Hijo del menu</param>
      ///// <param name="_valueMenu">Contiene el nombre del menu</param>
      ///// <param name="order">Contiene el orden en que se encuentra cada item encontrado</param>
      ///// <param name="_list">Lista que contiene todos los items del menu</param>
      //private void GenerarMenu(System.Windows.Forms.ToolStripItemCollection _Item, ref string _valueMenu, ref int order, ref List<EPlantillas> _list)
      //{
      //   try
      //   {
      //      int padre = order;
      //      for (int i = 0; i < _Item.Count; i++)
      //      {
      //         if (!(_Item[i] is ToolStripSeparator))
      //         {
      //            order++;
      //            _valueMenu += padre.ToString() + "." + order.ToString() + "\t" + _Item[i].Text + "\n";
      //            EPlantillas m_plantilla = new EPlantillas();
      //            CargarPlantilla(ref m_plantilla, order, padre, _Item[i].Text, "A");
      //            _list.Add(m_plantilla);

      //            if (((ToolStripMenuItem)(_Item[i])).DropDownItems.Count > 0)
      //            {
      //               GenerarMenu(((ToolStripMenuItem)(_Item[i])).DropDownItems, ref _valueMenu, ref order, ref _list);
      //            }
      //         }
      //         else if (_Item[i] is ToolStripSeparator)
      //         {
      //            order++;
      //            _valueMenu += padre.ToString() + "." + order.ToString() + "\t- \n";
      //            EPlantillas m_plantilla = new EPlantillas();
      //            CargarPlantilla(ref m_plantilla, order, padre, "-", "L");
      //            _list.Add(m_plantilla);
      //         }
      //      }
      //   }
      //   catch (Exception ex)
      //   {
      //      throw ex;
      //   }
      //}

      ///// <summary>
      ///// Funcion que permite cargar la clase EPlantilla para que contenga todos los valores requeridos para posteriormente
      ///// ser ingresado en la base de datos
      ///// </summary>
      ///// <param name="_plantilla">Plantilla que tiene que rellenar con los datos comunes</param>
      ///// <param name="key">Llave principal de la plantilla</param>
      ///// <param name="relative">Llave relativa de la plantilla</param>
      ///// <param name="text">Nombre del menu</param>
      ///// <param name="activo">Estado de la plantilla</param>
      //private void CargarPlantilla(ref EPlantillas _plantilla, int key, int relative, string text, string activo)
      //{
      //   try
      //   {
      //      _plantilla.APLI_CodApli = m_dataconexion.APLI_CodApli;
      //      _plantilla.PTLA_Activo = activo;
      //      _plantilla.PTLA_Key = key;
      //      _plantilla.PTLA_Relative = relative;
      //      _plantilla.PTLA_Text = text;
      //      _plantilla.PTLA_UsrCrea = m_datausuario.USER_CodUsr;
      //   }
      //   catch (Exception ex)
      //   {
      //      throw ex;
      //   }
      //}

      ///// <summary>
      ///// Funcion que recorre el listado de plantillas creado para ser grabado en la base de datos de administracion
      ///// </summary>
      ///// <param name="_menu">Lista a ser grabada</param>
      //private void GenerarMenu(ref List<EPlantillas> _menu)
      //{
      //   try
      //   {

      //      foreach (EPlantillas Item in _menu)
      //      {
      //         GrabarMenu(Item);
      //      }
      //   }
      //   catch (Exception ex)
      //   {
      //      throw ex;
      //   }
      //}

      ///// <summary>
      ///// Procedimiento que graba en la base de datos todo el menu
      ///// </summary>
      ///// <param name="_registro">Plantilla de registro</param>
      //private void GrabarMenu(EPlantillas _registro)
      //{
      //   try
      //   {
      //      DAEnterpriseValidate.AsignarProcedure("PTLASI_UnReg", System.Data.CommandType.StoredProcedure);
      //      //DAEnterpriseValidate.AgregarParametro("@PTLA_Key", _registro.PTLA_Key);
      //      //DAEnterpriseValidate.AgregarParametro("@APLI_CodApli", _registro.APLI_CodApli);
      //      //DAEnterpriseValidate.AgregarParametro("@PTLA_Relative", _registro.PTLA_Relative);
      //      //DAEnterpriseValidate.AgregarParametro("@PTLA_Text", _registro.PTLA_Text);
      //      //m_sql.AgregarParametro("@PTLA_Activo", _registro.PTLA_Activo);
      //      //m_sql.AgregarParametro("@Usuario", _registro.PTLA_UsrCrea);
      //      //m_sql.ExecuteNonQuery();
      //   }
      //   catch (Exception ex)
      //   {
      //      throw ex;
      //   }
      //}

      //#endregion

      //#region habilitar/dehabilitar el menu

      ///// <summary>
      ///// Procedimiento para obtener los valores del menu
      ///// </summary>
      ///// <returns>Valor para verificar que se cargo todo el menu correctamente</returns>
      //private bool ObtenerMenu()
      //{
      //   try
      //   {
      //      m_valueMenu = "";
      //      DataSet m_datos = new DataSet();
      //      l_Plantillas = new List<EPlantillas>();
      //      DAEnterpriseValidate.AsignarProcedure("PTLASS_UnUsuario", System.Data.CommandType.StoredProcedure);
      //      //m_sql.AgregarParametro("@CodApli", m_dataconexion.APLI_CodApli);
      //      //m_sql.AgregarParametro("@CodEmp", m_dataconexion.EMPR_Codigo);
      //      //m_sql.AgregarParametro("@CodUsr", m_datausuario.USER_CodUsr);
      //      m_datos = DAEnterpriseValidate.ExecuteDataSet();

      //      m_datos.Tables[0].TableName = "Plantillas";
      //      foreach (DataRow l_fila in m_datos.Tables[0].Rows)
      //      {
      //         EPlantillas l_eplantillas = new EPlantillas();
      //         EPlantillas.Cargar_Esquema(l_fila, ref l_eplantillas);
      //         l_Plantillas.Add(l_eplantillas);
      //      }
      //      if (l_Plantillas.Count == 0) return false;
      //      else return true;
      //   }
      //   catch (Exception ex)
      //   {
      //      throw ex;
      //   }
      //}

      ///// <summary>
      ///// Procediiento para colocar la propiedad respectiva a cada Item del menu, segun los permisos que tenga el usuario que 
      ///// valido su cuenta.
      ///// </summary>
      ///// <param name="_menu">Objeto MenuStrip que sera recorrido para habilitar y deshabilitar items.</param>
      //private void AsignarMenu(ref System.Windows.Forms.MenuStrip _menu)
      //{
      //   try
      //   {
      //      if (ObtenerMenu())
      //      {
      //         int i = 1;
      //         foreach (System.Windows.Forms.ToolStripMenuItem Item in _menu.Items)
      //         {
      //            string estado = getEstado(i, 0);
      //            m_valueMenu += i.ToString() + "\t" + Item.Text + " \n";
      //            if (estado == "I")
      //            {
      //               Item.Enabled = false;
      //            }
      //            else if (estado == "A")
      //            {
      //               Item.Enabled = true;
      //               if (Item.DropDownItems.Count > 0)
      //               {
      //                  AsignarMenu(Item.DropDownItems, ref m_valueMenu, ref i);
      //               }
      //            }
      //            i++;
      //         }
      //         m_empresa = true;
      //      }
      //      else
      //      {
      //         m_empresa = false;
      //         foreach (System.Windows.Forms.ToolStripMenuItem Item in _menu.Items)
      //         {
      //            Item.Enabled = false;
      //         }
      //         ACDialogos.MostrarMensajeInformacion("Información", "Ud. no tiene Acceso a la empresa seleccionada");
      //      }
      //   }
      //   catch (Exception ex)
      //   {
      //      ACDialogos.MostrarMensajeError("Permisos del Sistema", "No puede otorgar permisos, revise el problema y vuelva a intentarlo", ex);
      //   }
      //}

      ///// <summary>
      ///// Procedimiento recursivo que ingresara en todos los Items hijos del menu para otorgarles los permisos correspondientes.
      ///// </summary>
      ///// <param name="_Item">Contiene un menu o puede ser un valir</param>
      ///// <param name="_valueMenu"></param>
      ///// <param name="order">Llave por la cual se rige los permisos que se estan dando</param>
      //private void AsignarMenu(System.Windows.Forms.ToolStripItemCollection _Item, ref string _valueMenu, ref int order)
      //{
      //   try
      //   {
      //      int padre = order;
      //      for (int i = 0; i < _Item.Count; i++)
      //      {
      //         order++;
      //         if (!(_Item[i] is ToolStripSeparator))
      //         {
      //            string estado = getEstado(order, padre);
      //            _valueMenu += padre.ToString() + "." + order.ToString() + "\t" + _Item[i].Text + "\n";
      //            if (estado == "I")
      //            {
      //               _Item[i].Enabled = false;
      //            }
      //            else if (estado == "A")
      //            {
      //               _Item[i].Enabled = true;
      //               if (((ToolStripMenuItem)(_Item[i])).DropDownItems.Count > 0)
      //               {
      //                  AsignarMenu(((ToolStripMenuItem)(_Item[i])).DropDownItems, ref _valueMenu, ref order);
      //               }
      //            }
      //         }
      //      }
      //   }
      //   catch (Exception ex)
      //   {
      //      throw ex;
      //   }
      //}

      ///// <summary>
      ///// Procedimiento que devuelve el estado en el que se encuentra un Item del menu, para su respectiva habilitacion/inhabilitacion
      ///// </summary>
      ///// <param name="key">Campo llave con el que se lo buscara</param>
      ///// <param name="relative">Campo relativo que tambien sirve para su busqueda</param>
      ///// <returns>El estado del Item buscado</returns>
      //private string getEstado(int key, int relative)
      //{
      //   try
      //   {
      //      _key = key;
      //      _relative = relative;
      //      string estado = "";
      //      EPlantillas tmp = l_Plantillas.Find(getEstado);
      //      if (tmp == null)
      //      {
      //         estado = "A";
      //      }
      //      else
      //      {
      //         estado = tmp.PTLA_Activo;
      //      }
      //      return estado;
      //   }
      //   catch (Exception ex)
      //   {
      //      throw ex;
      //   }
      //}

      //private int _key;
      //private int _relative;
      //private bool getEstado(EPlantillas _list)
      //{
      //   if (_list.PTLA_Key == _key && _list.PTLA_Relative == _relative)
      //   {
      //      return true;
      //   }
      //   else
      //   {
      //      return false;
      //   }
      //}
      ///// <summary>
      ///// Carga el esquema de la plantilla.
      ///// </summary>
      ///// <param name="x_fila">Registro a ser cargado</param>
      ///// <param name="x_eplantillas">Plantilla a ser cargadas</param>
      //private void Cargar_Esquema(DataRow x_fila, ref EPlantillas x_eplantillas)
      //{
      //   try
      //   {
      //      if (x_fila.Table.Columns.Contains("APLI_CodApli"))
      //      {
      //         if (x_fila["APLI_CodApli"] != System.DBNull.Value)
      //         { x_eplantillas.APLI_CodApli = x_fila["APLI_CodApli"].ToString(); }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_Key"))
      //      {
      //         if (x_fila["PTLA_Key"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_Key = (Int32)x_fila["PTLA_Key"]; }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_Relative"))
      //      {
      //         if (x_fila["PTLA_Relative"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_Relative = (Int32)x_fila["PTLA_Relative"]; }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_Text"))
      //      {
      //         if (x_fila["PTLA_Text"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_Text = x_fila["PTLA_Text"].ToString(); }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_Activo"))
      //      {
      //         if (x_fila["PTLA_Activo"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_Activo = x_fila["PTLA_Activo"].ToString(); }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_TipSec"))
      //      {
      //         if (x_fila["PTLA_TipSec"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_TipSec = x_fila["PTLA_TipSec"].ToString(); }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_UsrCrea"))
      //      {
      //         if (x_fila["PTLA_UsrCrea"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_UsrCrea = x_fila["PTLA_UsrCrea"].ToString(); }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_FecCrea"))
      //      {
      //         if (x_fila["PTLA_FecCrea"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_FecCrea = (DateTime)x_fila["PTLA_FecCrea"]; }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_UsrMod"))
      //      {
      //         if (x_fila["PTLA_UsrMod"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_UsrMod = x_fila["PTLA_UsrMod"].ToString(); }
      //      }
      //      if (x_fila.Table.Columns.Contains("PTLA_FecMod"))
      //      {
      //         if (x_fila["PTLA_FecMod"] != System.DBNull.Value)
      //         { x_eplantillas.PTLA_FecMod = (DateTime)x_fila["PTLA_FecMod"]; }
      //      }
      //   }
      //   catch (Exception ex)
      //   { throw ex; }
      //}

      //#endregion
      #endregion

      #region Metodos

      #region Publicos
           
      /// <summary>
      /// Encriptar la cadena con el metodo seleccionado
      /// </summary>
      /// <param name="_cadena"></param>
      /// <param name="_algoritmo"></param>
      /// <returns></returns>
      public string getStringEncrypt(string _cadena, ACTypeAlgorithm _algoritmo)
      {
         try
         {
            switch (_algoritmo)
            {
               case ACTypeAlgorithm.csAlgotithmOnlyMd5:
                  return ObtenerMd5(_cadena);
               default:
                  return "Opcion no disponible para 1a cadena";
            }
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Encriptar una cadena con el metodo seleccionado usando 2 parametros de entrada
      /// </summary>
      /// <param name="_usuario">Usuario</param>
      /// <param name="_contrasena">Contraseña</param>
      /// <param name="_algoritmo">Algoritmo seleccionado</param>
      /// <returns></returns>
      public string getStringEncrypt(string _usuario, string _contrasena, ACTypeAlgorithm _algoritmo)
      {
         m_datausuario = new ACDataUsuario();
         m_datausuario.USER_CodUsr = _usuario;
         m_datausuario.USER_PassUsr = _contrasena;
         try
         {
            switch (_algoritmo)
            {
               case ACTypeAlgorithm.csAlgorithmPassMd5New:
                  cryptMd5();
                  break;
               case ACTypeAlgorithm.vbAlgorithmPasswordVold:
                  cryptVB6();
                  break;
               case ACTypeAlgorithm.vbAlgorithmPasswordVB6:
                  cryptVB6();
                  break;
               default:
                  return "Opcion no disponible para 2 cadenas";
            }
         }
         catch (Exception ex)
         {
            throw ex;
         }
         return m_send_user_passusr;
      }

      #endregion

      #endregion

      #region Eventos

      /// <summary>
      /// Metodo que genera la encriptacion de la contraseña para la validacion de usuario
      /// </summary>
      /// <param name="_algorithm">Codigo del algoritmo, que define que algoritmo que se utilizara</param>
      /// <param name="_usuario">Usuario que se desea validar</param>
      /// <param name="_clave">Contraseña que se desea utilizar</param>
      public void criptography(ACTypeAlgorithm _algorithm, string _usuario, string _contrasena)
      {
         try
         {
            m_datausuario = new ACDataUsuario();
            m_datausuario.USER_CodUsr = _usuario;
            m_datausuario.USER_PassUsr = _contrasena;
            m_algorithm = _algorithm;
            criptography();
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Funcion que Encripta la contraseña del usuario que se quiere validar
      /// </summary>
      private void criptography()
      {
         try
         {
            switch (m_algorithm)
            {
               case ACTypeAlgorithm.csAlgorithmPassMd5New: // Ecnriptar con MD5
                  cryptMd5();
                  break;
               case ACTypeAlgorithm.vbAlgorithmPasswordVB6: // Encriptar usando fnCodifica de NextSoft
                  cryptVB6();
                  break;
               default:
                  cryptMd5();
                  break;
            }
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Metodos principal de encriptacion, ejecutado desde el constructor
      /// </summary>
      private void encriptar()
      {
         try
         {
            // Encripta las contraseñas
            if (m_validarPassword) criptography();
            // Genera el SQL de consulta
            genSQLUsuario();
            DataSet m_datos = new DataSet();
            DAEnterpriseValidate.AsignarProcedure(m_sql_user, System.Data.CommandType.Text);
            // Ejecuta el procedimiento para cargar los datos del usuario
            m_datos = DAEnterpriseValidate.ExecuteDataSet();
            // Verificar que la consulta se ha ejecutado
            m_datos.Tables[0].TableName = "Resultados";
            // Cargar los datos del usuario
            string _user_iduser = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_IdUser"].ToString();
            string _user_codusr = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_codUsr"].ToString();
            string _user_nombre = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_Nombre"].ToString();
            string _user_desc = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_Desc"].ToString();
            string _user_passusr_db = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_PassUsr"].ToString();
            string _nive_codnivel = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["NIVE_Codigo"].ToString();
            // Verifica si tiene opcionde validacion de password
            if (m_validarPassword)
            {
               if (m_send_user_passusr.Trim() == _user_passusr_db.Trim())
               {
                  m_password = true;
                  if (_user_iduser != null)
                  {
                     genSQLProceso();
                     m_datos = new DataSet();
                     DAEnterpriseValidate.AsignarProcedure(m_sql_process, System.Data.CommandType.Text);
                     m_datos = DAEnterpriseValidate.ExecuteDataSet();
                     m_datos.Tables[0].TableName = "Resultados";
                     if (Convert.ToInt16(m_datos.Tables[0].Rows[0]["CntProcess"]) > 0)
                     { m_proceso = true; }
                     else
                     { m_proceso = false; }
                  }
                  else
                  { m_proceso = false; }
               }
               else
               { m_password = false; }
            }
            else
            {
               m_password = true;
               if (m_datausuario.USER_CodUsr != null)
               {
                  genSQLProceso();
                  m_datos = new DataSet();
                  DAEnterpriseValidate.AsignarProcedure(m_sql_process, System.Data.CommandType.Text);
                  m_datos = DAEnterpriseValidate.ExecuteDataSet();
                  m_datos.Tables[0].TableName = "Resultados";
                  if (Convert.ToInt16(m_datos.Tables[0].Rows[0]["CntProcess"]) > 0)
                  { m_proceso = true; }
                  else
                  { m_proceso = false; }
               }
               else
               { m_proceso = false; }
               m_password = false;
            }
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      private void EncriptarMultiple()
      {
         try
         {
            // Genera el SQL de consulta
            genSQLUsuario();
            DataSet m_datos = new DataSet();
            DAEnterpriseValidate.AsignarProcedure(m_sql_user, System.Data.CommandType.Text);
            // Ejecuta el procedimiento para cargar los datos del usuario
            m_datos = DAEnterpriseValidate.ExecuteDataSet();
            // Verificar que la consulta se ha ejecutado
            m_datos.Tables[0].TableName = "Resultados";
            // Cargar los datos del usuario
            string _user_iduser = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_IdUser"].ToString();
            string _user_codusr = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_codUsr"].ToString();
            string _user_nombre = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_Nombre"].ToString();
            string _user_desc = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_Desc"].ToString();
            string _user_passusr_db = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["USER_PassUsr"].ToString();
            string _nive_codnivel = m_datos.Tables[0].Rows.Count == 0 ? "" : m_datos.Tables[0].Rows[0]["NIVE_Codigo"].ToString();

            m_password = true;
            if (m_datausuario.USER_CodUsr != null)
            {
               genSQLTodosProceso();
               m_datos = new DataSet();
               m_listProcesos = new List<EProcesos>();
               DAEnterpriseValidate.AsignarProcedure(m_sql_process, System.Data.CommandType.Text);
               using (DbDataReader reader = (DbDataReader)DAEnterpriseValidate.ExecuteDataReader())
               {
                  if (reader.HasRows)
                  {
                     ACEsquemas _esquemas = new ACEsquemas(new EProcesos());
                     while (reader. Read())
                     {
                        EProcesos _procesos = new EProcesos();
                        _esquemas.ACCargarEsquemas(reader, _procesos);
                        m_listProcesos.Add(_procesos);
                     }
                  }
               }
               if (m_listProcesos.Count > 0)
               { m_proceso = true; }
               else
               { m_proceso = false; }
            }
            else
            { m_proceso = false; }
            m_password = false;

         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Algoritmo de encriptacion usando MD5
      /// </summary>
      private void cryptMd5()
      {
         try
         {
            int longUsr = m_datausuario.USER_CodUsr.Length;
            string tmp = ObtenerMd5(m_datausuario.USER_CodUsr);
            string _user_passusr = tmp.Substring(0, longUsr) + ObtenerMd5(m_datausuario.USER_PassUsr) + tmp.Substring(tmp.Length - longUsr, longUsr);
            m_send_user_passusr = ObtenerMd5(_user_passusr);
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Algoritmo de encriptacion usando el proceso en VB6
      /// </summary>
      private void cryptVB6()
      {
         try
         {
            if (m_datausuario.Cadena != null && m_datausuario.Cadena.Length > 0)
            {
               m_send_user_passusr = fncCodifica(m_datausuario.USER_PassUsr, m_datausuario.Cadena);
            }
            else
            {
               m_datausuario.Cadena = Vb.Strings.Chr(7).ToString() + Vb.Strings.Chr(20).ToString() + Vb.Strings.Chr(21).ToString() + Vb.Strings.Chr(15).ToString();
               m_send_user_passusr = fncCodifica(m_datausuario.USER_PassUsr, m_datausuario.Cadena);
            }
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Genera la consulta SQL a ejecutarse en la base de datos para la validacion del usuario
      /// </summary>
      private void genSQLUsuario()
      {
         try
         {
            string _sql_user = "SELECT USER_IdUser,USER_codUsr, USER_Nombre, USER_Desc, USER_PassUsr, NIVE_Codigo FROM Usuarios ";
            _sql_user += "WHERE USER_CodUsr = '{0}'";
            m_sql_user = String.Format(_sql_user, m_datausuario.USER_CodUsr);
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Genera la consulta SQL a ejecutarse en la base de datos para la validacion del proceso
      /// </summary>
      private void genSQLProceso()
      {
         try
         {
            string _sql_process = "SELECT count(*) As CntProcess FROM UsuariosProcesos";
            _sql_process += " WHERE USER_idUser = {0}" + Environment.NewLine;
            _sql_process += " AND APLI_Codigo = '{1}'" + Environment.NewLine;
            _sql_process += " AND EMPR_Codigo = '{2}'" + Environment.NewLine;
            _sql_process += " AND PROC_Codigo = '{3}'" + Environment.NewLine;

            m_sql_process = String.Format(_sql_process, new object[] { m_datausuario.USER_IdUser, m_datausuario.APLI_Codigo, m_datausuario.EMPR_Codigo, m_datausuario.PROC_Codigo });
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      /// <summary>
      /// Genera la consulta SQL a ejecutarse en la base de datos para la validacion del proceso
      /// </summary>
      private void genSQLTodosProceso()
      {
         try
         {
            string _sql_process = "SELECT * FROM UsuariosProcesos";
            _sql_process += " WHERE USER_idUser = {0}" + Environment.NewLine;
            _sql_process += " AND APLI_Codigo = '{1}'" + Environment.NewLine;
            _sql_process += " AND EMPR_Codigo = '{2}'" + Environment.NewLine;

            m_sql_process = String.Format(_sql_process, new object[] { m_datausuario.USER_IdUser, m_datausuario.APLI_Codigo, m_datausuario.EMPR_Codigo, m_datausuario.PROC_Codigo });
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      #endregion

      #region Algoritmos de Encriptacion

      /// <summary>
      /// Funcion que codifica una palabra usando MD5
      /// </summary>
      /// <param name="pass">Palabra que sera codificada</param>
      /// <returns>la cadena codificada con MD5 de longitud 32</returns>
      private string ObtenerMd5(string pass)
      {
         try
         {
            MD5 md5 = MD5CryptoServiceProvider.Create();
            byte[] dataMd5 = md5.ComputeHash(Encoding.Default.GetBytes(pass));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < dataMd5.Length; i++)
               sb.AppendFormat("{0:x2}", dataMd5[i]);
            return sb.ToString();
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      #region Encriptación Usando VB6.0
      /// <summary>
      /// Funcion que codifica la contraseña desarrollada en VB6
      /// </summary>
      /// <param name="cadena"></param>
      /// <param name="Pass"></param>
      /// <returns></returns>
      private string fncCodifica(string cadena, string Pass)
      {
         int i = 0;
         int j = 0;
         string cadresult = null;
         cadresult = "";
         i = 1;
         j = 1;
         try
         {
            while (i <= Vb.Strings.Len(cadena))
            {
               cadresult = cadresult + Vb.Strings.Chr(Vb.Strings.Asc(Vb.Strings.Mid(cadena, i, 1)) ^ Vb.Strings.Asc(Vb.Strings.Mid(Pass, j, 1)));
               if (j < Vb.Strings.Len(Pass))
               {
                  j = j + 1;
               }
               else
               {
                  j = 1;
               }
               i = i + 1;
            }
         }
         catch (Exception ex)
         {
            throw ex;
         }
         return cadresult;
      }
      private static byte Asc(char src)
      {
         try
         {
            return Convert.ToByte(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(src + "")[0]);
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }
      private static char Chr(byte src)
      {
         try
         {
            return (System.Text.Encoding.GetEncoding("iso-8859-1").GetChars(new byte[] { src })[0]);
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }
      private static char Mid(string s, int a, int b)
      {
         try
         {
            string temp = s.Substring(a - 1, b);
            return Convert.ToChar(temp);
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }
      #endregion

      #endregion

      #region Otros
      public enum CommandType
      {
         // Summary:
         //     An SQL text command. (Default.)
         Text = 1,
         StoredProcedure = 4,
         TableDirect = 512,
      }
      #endregion
   }
}
